package com.eden.door.util;


/*
* 时间：2010-07-09
* 作者：张剑桥
* 文件名：JiSuan.java
* 功能：计算字符串形式的加减乘除混合运算（包含括号）
*/
import java.util.Stack;
import java.util.Vector;

public class JiSuan {
private String data;    //原始表达式字符串
private Vector<String> devided; //分解后的表达式
private Vector<String> last;     //后缀表达式，有devided转化而来
public JiSuan(String data) {
   this.data = data;
   devided = getDevidedData();
   last = new Vector<String>();
   inToLast();
}
//中缀表达式转换成后缀表达式
public String calculator() {
   String result = "";
   Stack<String> stack = new Stack<String>();
   double a = 0;
   double b = 0;
   for(int i=0;i<last.size();i++) {
    String elem = last.get(i);
    if(elem == "+") {
     a = Double.parseDouble(stack.pop());
     b = Double.parseDouble(stack.pop());
     stack.push(""+(a+b));
    } else if(elem == "-") {
     a = Double.parseDouble(stack.pop());
     b = Double.parseDouble(stack.pop());
     stack.push(""+(b-a));
    } else if(elem == "*") {
     a = Double.parseDouble(stack.pop());
     b = Double.parseDouble(stack.pop());
     stack.push(""+(a*b));
    } else if(elem == "/") {
     a = Double.parseDouble(stack.pop());
     b = Double.parseDouble(stack.pop());
     stack.push(""+(b/a));
    } else {
     stack.push(elem);
    }
   }
   result = stack.pop();
   return result;
}
private void inToLast() {
   Stack<String> stack = new Stack<String>();
   stack.push("@");
   for(int i=0;i<devided.size();i++) {
    String elem = devided.get(i);
    if(elem.equals("(")) {
     stack.push(elem);
    } else if(elem.equals("*") || elem.equals("/") || elem.equals("+") || elem.equals("-")) {
     YunSuanFu a = new YunSuanFu(elem);
     YunSuanFu b = new YunSuanFu(stack.peek());
     while(a.compare(b) < 1) {
      if(stack.peek() != "@") {
       last.add(stack.pop());
       b = new YunSuanFu(stack.peek());
      } else {
       break;
      }
     }
     stack.push(elem);
    } else if(elem.equals(")")) {
     while(!stack.peek().equals("(")) {
      last.add(stack.pop());
     }
     stack.pop();
    }else {
     last.add(elem);
    }
   }
   while(stack.peek() != "@") {
    last.add(stack.pop());
   }
}
//此方法将一个字符串进行分割，并返回一个Vector<String>对象
private Vector<String> getDevidedData() {
   Vector<String> devidedData = new Vector<String>();
   String msg = "";
   char charactor;
   boolean isFuShu = false;
   int dataLength = data.length();
  
   for(int i=0;i<dataLength;i++) {
    charactor = data.charAt(i);
    switch(charactor) {
    case '+':
     if(!msg.equals(""))
      devidedData.add(msg);
     devidedData.add("+");
     msg = "";
     break;
    case '-':
     if(isFuShu) {
      msg = "-";
      break;
     }
     if(!msg.equals(""))
      devidedData.add(msg);
     devidedData.add("-");
     msg = "";
     break;
    case '*':
     if(!msg.equals(""))
      devidedData.add(msg);
     devidedData.add("*");
     msg = "";
     break;
    case '/':
     if(!msg.equals(""))
      devidedData.add(msg);
     devidedData.add("/");
     msg = "";
     break;
    case '(':
     devidedData.add("(");
     if(data.charAt(i+1) == '-') {
      isFuShu = true;
     }
     msg = "";
     break;
    case ')':
     if(isFuShu) {
      devidedData.set(devidedData.size()-1,msg);
      isFuShu = false;
     } else {
      devidedData.add(msg);
      devidedData.add(")");
     }
     msg = "";
     break;
     default:
      msg += charactor;
    }
   }
   if(!msg.equals("")) {
    devidedData.add(msg);
   }
   return devidedData;
}
//下面的类用于封装运算符，以便于对运算符的优先级进行比较
private class YunSuanFu {
   private String fuhao;
   private int jibie;
   public YunSuanFu(String fuhao) {
    this.fuhao = fuhao;
    if(fuhao == "@") {
     jibie = 0;
    } else if(fuhao == "+" || fuhao == "-") {
     jibie = 1;
    } else if(fuhao == "*" || fuhao == "/") {
     jibie = 2;
    } else if(fuhao == "(" || fuhao == ")") {//这里有些不同，这里把括号的优先级设低，主要是栈中运算符比较时的特殊情况，可参考上面的应用
     jibie = 0;
    }
   }
   public int compare(YunSuanFu b) {
    if(jibie > b.jibie) {
     return 1;
    } else if(jibie == b.jibie) {
     return 0;
    } else {
     return -1;
    }
   }
}

public static void main(String[] args) {
   JiSuan jiSuan = new JiSuan("34+3*4+(3*3)/3/2");
   System.out.println(jiSuan.calculator());//输出结果为19.5
}
}